Edit or run this notebook

The backstage of reactivity

by Nick aka malyvsen

11.9 μs

Hey there 👋 In this notebook, I'll try to convince you that you could have made Pluto yourself!

This notebook is part of PlutoCon 2021. It's best served together with my presentation 🎥

11.4 μs

Expression objects

If you write a colon : in front of some code, you get an expression object representing the syntax tree.

7.9 μs
:(toucan = 2 + can)
3.0 μs

This object has a .head and .args, which represent a node in the syntax tree and its children. In this case, .head is the assignment operator = and the children are the left-hand side (the variable being assigned to) and the right-hand side (the value being assigned).

4.2 μs
:(=)
2.4 μs
2.0 μs

The :toucan you're seeing here is a symbol object - it represents a variable name and can easily be turned into a string:

5.6 μs
"toucan"
1.1 μs

Also, check this out: args[2] is an expression object in itself!

4.0 μs
:(2 + can)
2.2 μs

Now for a little it of Julia magic: 2 + can is a function call to the function +:

3.8 μs
:call
1.4 μs
1.5 μs

.args[1] is the function being called, and the rest of .args is its arguments. So + is secretly a function!

4.1 μs
7
100 ns

One last thing about expression objects - you can easily make them out of strings like so:

3.4 μs
:(toucan = 2 + can)
146 μs

What variables does a cell use?

Let's write a function, references, which tells us exactly that!

4.9 μs
105 ms
references (generic function with 1 method)
35.6 μs
references (generic function with 2 methods)
24.7 μs
references (generic function with 3 methods)
14.8 μs

What variables does a cell assign to?

3.1 μs
5.3 ms
assignments (generic function with 1 method)
29.9 μs

When does one cell depend on another?

We'll write a function called depends_on which tells us whether cell a depends on cell b, i.e. whether b needs to be ran before a.

It's pretty easy! Try to figure it out before you proceed 🧙🏼 Here's how our function should behave:

6.0 μs
true
42.8 ms
false
251 μs

Tell me how it's done!

12.9 ms

TypeError: non-boolean (Missing) used in boolean context

  1. top-level scope@Local: 1
---
depends_on (generic function with 1 method)
49.8 μs

In what order should we run cells?

Julia's sort function can help here - it takes a "less than" argument, lt, which should be a function that returns true if its first argument should come before its second argument, and false otherwise.

5.6 μs
run_order (generic function with 1 method)
22.9 μs
337 μs

Actually running cells

Let's use Julia's Core.eval to run cells in the correct order.

The first argument to Core.eval is the module to evaluate the expression in - we'll just use Main. The second argument is an expression object.

6.1 μs
run_cell! (generic function with 1 method)
41.3 μs
3
270 μs
3
1.3 μs

We're almost there! The cells below are quite meta, so Pluto might have trouble updating them - please help it 😇

4.8 μs
run_cells! (generic function with 1 method)
19.9 μs
42.5 ms
4
1.3 μs
6
1.2 μs

Bam, we did it! I hope Pluto is still magic 🪄 after you got a sneak peek behind the curtain. Adieu!

4.9 μs
Loading...i